/**
 * 阿里云缓冲池. 先到缓存中拿如果拿不到再到阿里云去取.
 * 本地cache可加可不加..,如果添加本地cache策略, 那么要考虑更新策略
 *
 */
'use strict';
import * as zlibUtil  from  '../util/zlib-util';
import MemcacheService from './memcache-service';

const memcachedCachedTime = 60 * 60; // in second

import loadUpdateService from './oss-load-update-service';

export default class OssStore {

    loadService:loadUpdateService;

    memcachedService:MemcacheService;

    constructor(loadService:loadUpdateService, memcachedService:MemcacheService){
        this.loadService = loadService;
        this.memcachedService = memcachedService;
    }



    /**
     * 根据路径 选择用户的页面,
     * 首先从本地缓存中取, 如果没有 再从memcachedService中取,如果还没有,再到Oss中取
     * @param visitKey
     * @param response
     */
   async  getPageContent (visitKey,requestCallback?){

        let isString =  typeof visitKey ==='string';
        try{
            let requestResult;
            if(isString){
                requestResult = await requestSingleFile.call(this,visitKey,requestCallback);
            }else{
                requestResult=  await requestMutilFIle.call(this,visitKey,requestCallback);
            }
            return requestResult;
        }catch(err){
            console.error(err);
            throw err;
        }
    }


    /**
     * 删除memched缓存内容
     * 下次调用时会自动更新内部内容
     * @param visiteKey
     */
    async deleteFile (visiteKey){
        console.info('删除缓存',visiteKey);
       let result  =  await this.memcachedService.delete(visiteKey);
        return result;
    }

//从阿里云更新页面.
    async updatePageContent(visitKey,requestCallback) {

        try{
            let htmlContent =await (requestCallback?requestCallback():this.loadService.requestOssFile(visitKey));
            htmlContent=  await saveDealContent(visitKey,htmlContent);
            this.memcachedService.set(visitKey, htmlContent, memcachedCachedTime);
            return true;
        }catch(err){
            console.warn(visitKey, '失败了. ', err);
            return false;
        }
    }



}

/**
 * 批量请求的情况.
 * @param keyArrays
 * @param requestCallback
 */
async function requestMutilFIle(keyArrays,requestCallback){
    //console.time('MutilFIle从memcached获取文件');
    console.info('MutilFIle从memcached获取文件::',keyArrays);
    let fileMap  = await this.memcachedService.getMulti(keyArrays);
    //console.timeEnd('MutilFIle从memcached获取文件');

    //看那些key没有, 如果没有的话到阿里云上去取
    let questArray = [];
    let keyReault = [];

    for(let i=0,ilen=keyArrays.length;i<ilen;i++){
        let ossPath  = keyArrays[i];
        if(typeof fileMap[ossPath] === 'undefined'){
            console.info('从memcachedService获取数据发生错误了:可能是里面没有这个值,或值过期了,重新获取吧,visitKey:',ossPath);
            questArray.push(requestCallback?requestCallback(ossPath):this.loadService.requestOssFile(ossPath));
            keyReault.push(ossPath);
        }else{

        }
    }

    console.time("从阿里云拿文件");
    let mutilReq  = await Promise.all(questArray);
    console.timeEnd("从阿里云拿文件");
    console.time("把阿里云拿到的文件进行处理放到缓存中");
    for(let i=0,ilen=keyReault.length;i<ilen;i++){
        fileMap[keyReault[i]]=mutilReq[i];
        let result  = await saveDealContent(keyReault[i],mutilReq[i]);
        this.memcachedService.set(keyReault[i],result,memcachedCachedTime);
    }
    console.timeEnd("把阿里云拿到的文件进行处理放到缓存中");
    return fileMap;
}


/**
 *
 * @param visitKey
 * @param requestCallback
 * @returns {*}
 */
async function requestSingleFile(visitKey,requestCallback){
    //console.time('Single从memcached获取文件');
    let htmlContentZip = await this.memcachedService.get(visitKey);
    //console.timeEnd('Single从memcached获取文件:',visitKey);
    console.info('Single从memcached获取文件::',visitKey);

    if( typeof  htmlContentZip !== 'undefined'){ //只要有值了
        return htmlContentZip;
    } else {
        console.info('从memcachedService获取数据发生错误了:可能是里面没有这个值,或值过期了,重新获取吧,visitKey:',visitKey,'--');
        //直接从阿里云上取
        try{
            let htmlContent  = await (requestCallback?requestCallback(visitKey):this.loadService.requestOssFile(visitKey));
            let result  = await  saveDealContent(visitKey,htmlContent);
            this.memcachedService.set(visitKey,result,memcachedCachedTime);
            return result;
        }catch(err){
            console.warn(visitKey,'失败了. ',err);
            throw err;
        }
    }
}

/**
 * 处理文件看是否密
 * @param visiteKey
 * @param content
 * @returns {*}
 */
async function saveDealContent(visiteKey,content){

    if(visiteKey.endsWith('.co') ||visiteKey.endsWith('.json') ||visiteKey.endsWith('.js') || visiteKey.endsWith('.css') ){
        return content;
    } else {
        let zipContent  =  await zlibUtil.gzip(content);
        return zipContent;
    }
}

function zipContent(contentZip) : Promise<string>{
    console.time("压缩文件")
    return new Promise((resolve,reject)=>{
        zlibUtil.gzip(contentZip).then(resultContent=>{
            resolve(resultContent);
        });
    });
}